package gbench.sandbox.matrix.img;

import java.util.Arrays;
import java.util.stream.Collectors;

import org.junit.jupiter.api.Test;

import gbench.common.tree.LittleTree;
import gbench.common.tree.LittleTree.IRecord;
import gbench.sandbox.matrix.img.util.BlasMatrix;
import gbench.sandbox.matrix.img.util.MatlibCanvas.NVec;
import gbench.sandbox.matrix.img.util.MatlibCanvas.Range;

/**
 * 
 * @author gbench
 *
 */
public class JunitMatlibMx {
    
    @Test
    public void foo() {
        final var size = 5;
        final var mx = NVec.of(Range.of(size*size).dblA2(e->e%(size+1)==0?1:0)).reshape2mx(size, size); // 单位矩阵
        System.out.println(mx);
        final var vec0 = NVec.of(1).reshape(BlasMatrix::of, 10);
        System.out.println("10:"+vec0);
        final var vec = NVec.of(1).reshape(BlasMatrix::of, 10,1);
        System.out.println("10x1:"+vec);
        final var vec2 = NVec.of(1).reshape(BlasMatrix::of, 10,3);
        System.out.println("10x3:"+vec2);
        final var vec3 = NVec.of(1).reshape(BlasMatrix::of, 10,3,3);
        System.out.println("10x3x3:"+vec3);
    }
    
    @Test
    public void bar() {
        final var size = 5;// 矩阵尺寸
        final var mx = NVec.of(Range.of(size*size).dblA2(e->e%(size+1)==0?1:0)).reshape(BlasMatrix::dmx,size, size); // 单位矩阵
        System.out.println(mx);
        final var vec0 = NVec.of(1).reshape(BlasMatrix::dmx, 10);
        System.out.println("10:"+vec0);
        final var vec = NVec.of(1).reshape(BlasMatrix::dmx, 10,1);
        System.out.println("10x1:"+vec);
        final var vec2 = NVec.of(1).reshape(BlasMatrix::dmx, 10,3);
        System.out.println("10x3:"+vec2);
        final var vec3 = NVec.of(1).reshape(BlasMatrix::dmx, 10,3,3);
        System.out.println("10x3x3:"+vec3);
    }
    
    @Test
    public void qux() {
        final var r = Range.of(10).collect(IRecord.ssclc(e->e.toArray(Double[]::new)));
        System.out.println(Arrays.deepToString(r));
        final var r1 = Range.of(10).collect(Range.aaclc(NVec::of));
        System.out.println(r1);
        
        System.out.println(NVec.of(1,3).idval_set(0, 8));
        System.out.println(NVec.intdiv(10, 3));
    }
    
    @Test
    public void qux1() {
        final var x = NVec.of(1,3,1);
        final var p = NVec.of(Range.of(x.size())).reverse().alter(e->Math.pow(10, e)).dot(x); // 数字拼接成整数
        System.out.println(x+"-->"+p);
    }
    
    /**
     * 向量的列顺序编排成矩阵
     */
    @Test
    public void bar1() {
        int  width = 3;// 矩阵的列数宽度
        int  height = 4;// 矩阵高度/行数
        final var data = NVec.of(Arrays.asList(0,1,2,3,4,5,6,7,8,9,10,11));// 源数据
        System.out.println("原始数据:"+data);
        System.out.println("行序矩阵");
        System.out.println(data.reshape2mx(height, width));
        final var mx = data.collect(IRecord.ssclc(stream->{
            final var ss = stream.map(LittleTree.kvp()).map(a->{
                final var step = height;// 跳跃步长。
                final var index = NVec.intdiv(a._1(), step); // 求出id号索引的 行序的2维坐标
                final var wts = NVec.of(step,1);// wts 权重
                final var id = wts.dot(index.reverse());// 行列调转,生成id号码
                return new Double[] {id,a._2()};
            }).sorted((a,b)->a[0].compareTo(b[0])) //  根据索引号进行排序
            .map(aa->aa[1]);// 提取数据结果
            final var vec = NVec.of(ss.toArray(Double[]::new));
            System.out.println("行列调转后的结果:"+vec);
            return NVec.of(vec).reshape2mx(height,width);// 转置后的矩阵
        }));
        System.out.println("列序矩阵");
        System.out.println(mx);
    }
    
    @Test
    public void foo1() {
        // 投掷色子的测试
        final var dice = Range.of2(1,6);
        System.out.println(dice.list(e->e));
        final var n = Range.cph(dice,dice,dice,dice).count();
        System.out.println(n);
        
        Range.cph(dice,dice,dice,dice)
        .filter(e->e.stream().filter(o->o==6d).findAny().isPresent())
        .collect(Collectors.groupingBy(e->e.stream().filter(o->o==6).count()))
        .forEach((k,v)->{
            System.out.println(k+"---->"+v.size());
            System.out.println(v);
        });
        
        final var map = NVec.of(Range.of(1,1000)).groupBy(e->e%2==0,Collectors.summarizingDouble(e->e));
        System.out.println(map);
    }

}
